package cn.ch.train.business.service;

import cn.ch.train.business.domain.TrainCarriage;
import cn.ch.train.business.domain.TrainSeat;
import cn.ch.train.business.domain.TrainSeatExample;
import cn.ch.train.business.enums.SeatColEnum;
import cn.ch.train.business.mapper.TrainSeatMapper;
import cn.ch.train.business.request.TrainSeatQueryParam;
import cn.ch.train.business.request.TrainSeatSaveParam;
import cn.ch.train.business.response.TrainSeatQueryResult;
import cn.ch.train.common.response.PageResult;
import cn.ch.train.common.util.SnowUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
public class TrainSeatService {
    private static final Logger logger = LoggerFactory.getLogger(TrainSeatService.class);
    @Resource
    private TrainSeatMapper trainSeatMapper;
    @Resource
    private TrainCarriageService trainCarriageService;

    public void save(TrainSeatSaveParam param) {
        DateTime now = DateTime.now();
        TrainSeat trainSeat = BeanUtil.copyProperties(param, TrainSeat.class);
        if (Objects.isNull(trainSeat.getId())) {
            trainSeat.setId(SnowUtil.getSnowFlakeNextId());
            trainSeat.setCreateTime(now);
            trainSeat.setUpdateTime(now);
            trainSeatMapper.insert(trainSeat);
        } else {
            trainSeat.setUpdateTime(now);
            trainSeatMapper.updateByPrimaryKey(trainSeat);
        }
    }

    public PageResult<TrainSeatQueryResult> queryList(TrainSeatQueryParam param) {
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        trainSeatExample.setOrderByClause("train_code asc, carriage_index asc, row asc, col asc");
        TrainSeatExample.Criteria criteria = trainSeatExample.createCriteria();
        if (ObjectUtil.isNotEmpty(param.getTrainCode())) {
            criteria.andTrainCodeEqualTo(param.getTrainCode());
        }
        PageHelper.startPage(param.getPageNo(), param.getPageSize());
        List<TrainSeat> trainSeatList = trainSeatMapper.selectByExample(trainSeatExample);

        PageInfo<TrainSeat> trainSeatPageInfo = new PageInfo<>(trainSeatList);
        logger.info("总行数：{}", trainSeatPageInfo.getTotal());
        logger.info("总页数：{}", trainSeatPageInfo.getPages());
        List<TrainSeatQueryResult> trainSeatQueryList = BeanUtil.copyToList(trainSeatList, TrainSeatQueryResult.class);
        PageResult<TrainSeatQueryResult> pageResult = new PageResult<>();
        pageResult.setTotal(trainSeatPageInfo.getTotal());
        pageResult.setList(trainSeatQueryList);
        return pageResult;
    }

    public void delete(Long id) {
        trainSeatMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    public void genTrainSeat(String trainCode) {
        DateTime now = DateTime.now();
        // 批量生成的功能必须考虑的问题：
        // 1. 能不能支持重复生成？存在就跳过？or先删除重新生成？
        // 2. 批量生成时的事务？
        // step1：清空当前车次下的所有的座位记录
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        TrainSeatExample.Criteria criteria = trainSeatExample.createCriteria();
        criteria.andTrainCodeEqualTo(trainCode);
        trainSeatMapper.deleteByExample(trainSeatExample);
        // step2：查找当前车次下的所有的车厢
        List<TrainCarriage> trainCarriageList = trainCarriageService.selectByTrainCode(trainCode);
        // step3：循环生成每个车厢的座位
        for (TrainCarriage trainCarriage : trainCarriageList) {
            // 拿到车厢数据：行数、座位类型(可以根据座位类型得到列数)
            Integer rowCount = trainCarriage.getRowCount();
            String seatType = trainCarriage.getSeatType();
            int seatIndex = 1;
            // 根据车厢的座位类型，筛选出所有的列，比如车厢类型是一等座，则筛选出columnList={ACDF}
            List<SeatColEnum> colsByType = SeatColEnum.getColsByType(seatType);
            // 循环行数
            for (int row = 1; row <= rowCount; row++) {
                // 循环列数
                for (SeatColEnum seatColEnum : colsByType) {
                    // 构造座位数据并保存数据库
                    TrainSeat trainSeat = new TrainSeat();
                    trainSeat.setId(SnowUtil.getSnowFlakeNextId());
                    trainSeat.setTrainCode(trainCode);
                    trainSeat.setCarriageIndex(trainCarriage.getIndex());
                    trainSeat.setRow(StrUtil.fillBefore(String.valueOf(row), '0', 2));
                    trainSeat.setCol(seatColEnum.getCode());
                    trainSeat.setSeatType(seatType);
                    trainSeat.setCarriageSeatIndex(seatIndex++);
                    trainSeat.setCreateTime(now);
                    trainSeat.setUpdateTime(now);
                    trainSeatMapper.insert(trainSeat);
                }
            }
        }
    }
}
